package me.sealer.jmx.agent;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.jmx.JMXConfigurator;
import com.sun.jdmk.comm.HtmlAdaptorServer;
import lombok.extern.slf4j.Slf4j;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.rmi.registry.LocateRegistry;

/**
 * @author sealer
 * @date 2018/01/22.
 */
@Slf4j
public class ReloadConfigJmx {

    public static final String DOMAIN_NAME = "me.sealer.jmx";
    public static final String RELOAD_CONFIG_NAME = "reloadConfig";
    public static final String CONNECTOR_NAME = "htmlConnector";
    private static MBeanServer mBeanServer;
    private static JMXConfigurator jmxConfigurator;
    private static HtmlAdaptorServer htmlAdaptorServer;
    private static JMXConnectorServer jmxConnectorServer;
    private static final int HTML_PORT = 8092;
    private static final int RMI_PORT = 8888;

    public static void init(LoggerContext loggerContext) throws Exception {
        mBeanServer = MBeanServerFactory.createMBeanServer(DOMAIN_NAME);
        // 注册服务
        ObjectName objectName = new ObjectName(DOMAIN_NAME + ":name=" + RELOAD_CONFIG_NAME);
        jmxConfigurator = new JMXConfigurator(loggerContext, mBeanServer, objectName);
        mBeanServer.registerMBean(jmxConfigurator, new ObjectName(DOMAIN_NAME + ":name=" + RELOAD_CONFIG_NAME));

        // htmlAdaptor 注册连接
        htmlAdaptorServer = new HtmlAdaptorServer();
        htmlAdaptorServer.setPort(HTML_PORT);
        objectName = new ObjectName(DOMAIN_NAME + ":name=" + CONNECTOR_NAME);
        mBeanServer.registerMBean(htmlAdaptorServer, objectName);
        htmlAdaptorServer.start();

        // rmi方式
        //这句话非常重要，不能缺少！注册一个端口，绑定url后，客户端就可以使用rmi通过url方式来连接JMXConnectorServer
        LocateRegistry.createRegistry(RMI_PORT);
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + RMI_PORT + "/logback_config");
        jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mBeanServer);
        jmxConnectorServer.start();
    }

    public static void destroy() throws Exception {
        htmlAdaptorServer.stop();
        jmxConnectorServer.stop();
        mBeanServer = null;
        jmxConfigurator = null;
        htmlAdaptorServer = null;
        jmxConnectorServer = null;
    }
}

